<?php

namespace services\marketing;

use common\models\patient\User;
use Yii;
use common\components\Service;
use common\models\marketing\Tags;
use common\models\marketing\TagsGroup;
use yii\helpers\Json;

/**
 * Class TagsService
 * @package services\marketing
 */
class TagsService extends Service
{
    /**
     * 根据ID查找信息
     *
     * @param int $id
     * @return Tags|null
     */
    public function findById(int $id = 0): ?Tags
    {
        return Tags::find()->where(['id' => $id])->one();
    }

    /**
     * 查找信息
     *
     * @param array $condition
     * @return Tags|null
     */
    public function findInfo(array $condition = []): ?Tags
    {
        $query = Tags::find();

//        isset($condition['project_id']) && $query->andWhere(['project_id' => $condition['project_id']]);
//        isset($condition['name']) && $query->andWhere(['name' => $condition['name']]);
//        isset($condition['status']) && $query->andWhere(['status' => $condition['status']]);

        return $query->one();
    }

    /**
     * 查找列表
     *
     * @param array $condition
     * @return array|\yii\db\ActiveRecord[]
     */
    public function findList(array $condition = [])
    {
        $query = Tags::find();

        // select
        isset($condition['select']) && $query->select($condition['select']);

        // condition
        isset($condition['id']) && $query->andWhere(['id' => $condition['id']]);
        isset($condition['project_id']) && $query->andWhere(['project_id' => $condition['project_id']]);
        isset($condition['status']) && $query->andWhere(['status' => $condition['status']]);

        return $query->asArray()->all();
    }


    /**
     * 标签列表
     *
     * @return array
     */
    public function getList($projectId)
    {
        $list = TagsGroup::find()->select('id, group_name, is_inhibit_delete')
            ->where(['status' => TagsGroup::STATUS_ENABLE, 'project_id' => $projectId])
            ->orderBy(['id' => SORT_DESC])
            ->asArray()
            ->all();

        foreach ($list as &$val) {
            $tags = Tags::find()->select('id, tags_name')->where(['tags_group_id' => $val['id'], 'status' => Tags::STATUS_ENABLE])->asArray()->all();

            if ($tags) {
                foreach ($tags as &$t) {
                    $t['have_bind'] = $this->checkPatientHaveTags($t['id']);
                }
                $val['tags_name'] = implode('/', array_column($tags, 'tags_name'));
                $val['tags_list'] = $tags;
            } else {
                $val['tags_name'] = '';
            }
        }
        return [
            'list' => $list,
        ];
    }

    /**
     * 新增标签
     *
     * @param $params
     * @return array
     * @throws \Exception
     */
    public function create($params)
    {
        $transaction = Yii::$app->db->beginTransaction();
        try {
            // 新增标签组
            $tagsGroupId = $this->createTagsGroup($params);

            // 不是数字则为有错，直接返回
            if (!is_int($tagsGroupId)) {
                return $tagsGroupId;
            }

            // 批量新增子标签
            if ($params['list']) {
                $this->createTags($params['list'], $params, $tagsGroupId);
            }

            $transaction->commit();
            return ['code' => 200, 'message' => '新增成功'];
        } catch (\Exception $exception) {
            $transaction->rollBack();
            throw new \Exception($exception->getMessage(), 500);
        }
    }

    /**
     * 新增标签组
     *
     * @param $params
     * @return array|int
     */
    public function createTagsGroup($params)
    {
        $exists = $this->checkTagsGroupName([
            'group_name' => $params['group_name'],
            'project_id' => $params['project_id'],
            'status' => [TagsGroup::STATUS_ENABLE, TagsGroup::STATUS_INVALID]
        ]);
        if ($exists) {
            return ['code' => 422, 'message' => '该标签组名称已存在'];
        }

        $model = new TagsGroup();
        $model->group_name = $params['group_name'];
        $model->project_id = $params['project_id'];
        $model->status = TagsGroup::STATUS_ENABLE;
        $model->is_inhibit_delete = TagsGroup::INHIBIT_DELETE;
        $model->operation_id = $params['member_id'];
        if ($model->save() == false) {
            return ['code' => 422, 'message' => '新增失败'];
        }
        return $model->id;
    }

    /**
     * 判断标签组是否存在
     *
     * @param $where
     * @return bool
     */
    public function checkTagsGroupName($where)
    {
        return TagsGroup::find()->where($where)->exists();
    }

    /**
     * 编辑标签
     *
     * @param array $params
     * @return array
     * @throws \Exception
     */
    public function update(array $params)
    {
        $transaction = Yii::$app->db->beginTransaction();
        try {
            $exists = $this->checkTagsGroupName(['id' => $params['id']]);
            if (!$exists) {
                return ['code' => 422, 'message' => '数据不存在'];
            }

            $model = TagsGroup::findOne($params['id']);
            $tagsGroupIs = TagsGroup::findOne(
                [
                    'group_name' => $params['group_name'],
                    'project_id' => $params['project_id'],
                    'status' => [TagsGroup::STATUS_ENABLE, TagsGroup::STATUS_INVALID],
                ]
            );
            if ($tagsGroupIs && $tagsGroupIs->id != $params['id']) {
                return ['code' => 422, 'message' => '该标签组名称已存在'];
            }

            // 批量更新子标签状态
            // $this->updateTagsStatus($params['delete_tags_id']);

            // 批量新增子标签
            if ($params['list']) {
                $this->createTags($params['list'], $params, $params['id']);
            }

            $model->group_name = $params['group_name'];
            $model->project_id = $params['project_id'];
            $model->operation_id = $params['member_id'];
            if ($model->save() == false) {
                return ['code' => 422, 'message' => '修改失败'];
            }
            $transaction->commit();
            return ['code' => 200, 'message' => '修改成功'];

        } catch (\Exception $exception) {
            $transaction->rollBack();
            throw new \Exception($exception->getMessage(), 500);
        }
    }

    /**
     * 逻辑删除标签
     *
     * @Interface updateTagsStatus
     * @param $deleteTagsIds 删除的标签ID
     * @return int
     */
    public function updateTagsStatus($deleteTagsIds)
    {
        if (is_array($deleteTagsIds)) {
            // 删除标签，修改患者表冗余字段
            foreach ($deleteTagsIds as $val) {
                $this->updatePatientTagsName($val, '');
            }
            \common\models\patient\Tags::updateAll(['status' => Tags::STATUS_DELETE], ['tags_id' => $deleteTagsIds]);
        } else {
            $this->updatePatientTagsName($deleteTagsIds, '');
            return \common\models\patient\Tags::updateAll(['status' => Tags::STATUS_DELETE], ['tags_id' => $deleteTagsIds]);

        }
        return Tags::updateAll(['status' => Tags::STATUS_DELETE], ['id' => $deleteTagsIds]);
    }

    /**
     * 批量新增子标签
     *
     * @param $tagsList
     * @param $params
     * @param $tagsGroupId
     * @return int
     * @throws \yii\db\Exception
     */
    public function createTags($tagsList, $params, $tagsGroupId)
    {
        $addList = [];
        foreach ($tagsList as $val) {

            // ID不是0时则修改
            if ($val['tags_id'] != 0) {
                // 更新患者标签（冗余字段）
                $this->updatePatientTagsName($val['tags_id'], $val['tags_name']);

                Tags::updateAll(['tags_name' => $val['tags_name']], ['id' => $val['tags_id']]);
                continue;
            }
            $add['tags_name'] = $val['tags_name'];
            $add['tags_group_id'] = $tagsGroupId;
            $add['project_id'] = $params['project_id'];
            $add['status'] = TagsGroup::STATUS_ENABLE;
            $add['operation_id'] = $params['member_id'];
            $add['created_at'] = time();
            $add['updated_at'] = time();
            $addList[] = $add;
        }
        if ($addList) {
            return Yii::$app->db->createCommand()
                ->batchInsert(Tags::tableName(),
                    ['tags_name', 'tags_group_id', 'project_id', 'status', 'operation_id', 'created_at', 'updated_at'],
                    $addList)
                ->execute();
        }
        return true;
    }

    /**
     * 删除标签
     *
     * @param int $id
     * @return array
     * @throws \Exception
     */
    public function delete(int $id)
    {
        $transaction = Yii::$app->db->beginTransaction();
        try {
            $exists = $this->checkTagsGroupName(['id' => $id]);
            if (!$exists) {
                return ['code' => 422, 'message' => '该标签不存在'];
            }

            if (Tags::find()->where(['status' => Tags::STATUS_ENABLE, 'tags_group_id' => $id])->exists()) {
                return ['code' => 422, 'message' => '标签组下有子标签，不能删除'];
            }
            // $data1 = Tags::updateAll(['status' => Tags::STATUS_DELETE], ['tags_group_id' => $id]);
            $data2 = TagsGroup::updateAll(['status' => Tags::STATUS_DELETE], ['id' => $id]);
            if (!$data2) {
                return ['code' => 422, 'message' => '删除失败'];
            }
            $transaction->commit();
            return ['code' => 200, 'message' => '删除成功'];

        } catch (\Exception $exception) {
            $transaction->rollBack();
            throw new \Exception($exception->getMessage(), 500);
        }
    }

    /**
     * 更新患者标签（冗余字段）
     *
     * @param $tagsId
     * @param $newTagsName
     * @return bool
     */
    public function updatePatientTagsName($tagsId, $newTagsName)
    {
        // 旧的标签
        $oldTagsName = Tags::findOne(['id' => $tagsId]);

        // 需要更新患者标签ID
        $patientUser = \common\models\patient\Tags::find()
            ->select('patient_user_id')
            ->where(['tags_id' => $tagsId])
            ->asArray()
            ->all();
        $patientUserIds = array_column($patientUser, 'patient_user_id');

        $patientUserList = User::find()->select('id, patient_tags_name')->where(['id' => $patientUserIds])->asArray()->all();

        foreach ($patientUserList as $val) {

            $patientTagsName = explode(',', $val['patient_tags_name']);

            foreach ($patientTagsName as $k => $ptn) {
                if ($ptn == $oldTagsName->tags_name) {
                    if ($newTagsName) {
                        $patientTagsName[$k] = $newTagsName;
                    } else {
                        unset($patientTagsName[$k]);
                    }
                }
            }
            // 新的患者标签
            $newPatientTags = implode(',', $patientTagsName);
            User::updateAll(['patient_tags_name' => $newPatientTags], ['id' => $val['id']]);
        }
        return true;
    }

    /**
     * 判断标签是否存在
     *
     * @param $where
     * @return bool
     */
    public function checkTagsName($where)
    {
        return Tags::find()->where($where)->exists();
    }

    /**
     * 删除子标签
     *
     * @param $tagsId 标签ID
     * @return array
     * @throws \Exception
     */
    public function deleteTagsChild($tagsId)
    {
        $transaction = Yii::$app->db->beginTransaction();
        try {
            $exists = $this->checkTagsName(['id' => $tagsId]);
            if (!$exists) {
                return ['code' => 422, 'message' => '该标签不存在'];
            }
            $this->updateTagsStatus(intval($tagsId));
            $data = Tags::updateAll(['status' => Tags::STATUS_DELETE], ['id' => $tagsId]);
            if (!$data) {
                return ['code' => 422, 'message' => '删除失败'];
            }
            $transaction->commit();
            return ['code' => 200, 'message' => '删除成功'];
        } catch (\Exception $exception) {
            $transaction->rollBack();
            throw new \Exception($exception->getMessage(), 500);
        }
    }

    public function checkPatientHaveTags($tagsId)
    {
        // 查看是否存在患者已绑定当前标签
        $patientUser = \common\models\patient\Tags::find()
            ->select('patient_user_id')
            ->where(['tags_id' => $tagsId])
            ->asArray()
            ->all();
        // 存在返回0
        if ($patientUser) {
            return 0;
        }
        // 1为可以删除
        return 1;
    }

}